<template>
  <div v-if="visible" class="modal-overlay" @click="handleOverlayClick">
    <div class="modal-container" @click.stop>
      <div class="modal-header">
          <h3>管理员审批</h3>
          <div class="header-actions">
            <button class="close-btn" @click="handleClose">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <line x1="18" y1="6" x2="6" y2="18"></line>
                <line x1="6" y1="6" x2="18" y2="18"></line>
              </svg>
            </button>
          </div>
        </div>
        <div class="modal-body">
        <!-- 加载状态 -->
        <div v-if="loading" class="loading-state">
          <div class="loading-spinner"></div>
          <p>加载中...</p>
        </div>
        
        <!-- 错误信息 -->
        <div v-else-if="error" class="error-state">
          <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#ff4d4f" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="12" cy="12" r="10"></circle>
            <line x1="12" y1="8" x2="12" y2="12"></line>
            <line x1="12" y1="16" x2="12.01" y2="16"></line>
          </svg>
          <p>{{ error }}</p>
        </div>
        
        <!-- 任务数据 -->
        <div v-else>
          <!-- 任务类型和描述 -->
          <div class="task-basic-info">
            <h4>任务类型</h4>
            <div class="task-type-name">{{ taskInfo.taskTypeName || '-' }}</div>
            
            <h4>任务描述</h4>
            <div class="task-description" v-if="taskInfo.taskDescription">
              <div v-html="parseMarkdown(taskInfo.taskDescription)"></div>
            </div>
            <div class="no-data" v-else>
              <p>暂无任务描述</p>
            </div>
          </div>
          
          <!-- 状态信息 -->
          <div class="task-status-info">
            <h4>状态信息</h4>
            <div class="info-grid">
              <div class="info-item">
                <span class="info-label">任务状态：</span>
                <span class="info-value status-badge" :class="`status-${taskInfo.status || 'unknown'}`">
                  {{ taskInfo.statusText || '-' }}
                </span>
              </div>
              <div class="info-item">
                <span class="info-label">审批人：</span>
                <span class="info-value">{{ taskInfo.approverName || '-' }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">审批人ID：</span>
                <span class="info-value">{{ taskInfo.approverAuthId || '-' }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">流程名称：</span>
                <span class="info-value">{{ taskInfo.flowName || '-' }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">节点名称：</span>
                <span class="info-value">{{ taskInfo.nodeName || '-' }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">创建时间：</span>
                <span class="info-value">{{ formatDate(taskInfo.createTime) }}</span>
              </div>
            </div>
          </div>
          
          <!-- 原始数据 -->
          <div class="task-json-data" v-if="taskInfo.rawData">
            <h4>原始数据</h4>
            <div class="json-container">
              <pre>{{ JSON.stringify(parseRawData(), null, 2) }}</pre>
            </div>
          </div>
          
          <!-- 额外字段 -->
          <div class="task-json-data" v-if="taskInfo.extraFields">
            <h4>额外字段</h4>
            <div class="json-container">
              <pre>{{ JSON.stringify(parseExtraFields(), null, 2) }}</pre>
            </div>
          </div>
          
          <!-- 节点内容 -->
          <div class="task-node-content" v-if="taskInfo.nodeContent">
            <h4>节点内容</h4>
            <div class="node-content-form">
              <div v-if="getParsedNodeContent(taskInfo.nodeContent).length > 0" class="form-designer-components">
                <div v-for="(component, index) in getParsedNodeContent(taskInfo.nodeContent)" :key="component.id || index" class="form-component">
                  <component-renderer 
                    :component="component" 
                    :model-value="formValues[component.name || `field_${index}`]" 
                    @update:model-value="updateFormValue(component.name || `field_${index}`, $event)"
                  />
                </div>
              </div>
              
              <!-- 如果解析失败，显示原始JSON -->
              <div v-else class="fallback-json-display">
                <p class="fallback-info">无法解析表单组件，显示原始数据：</p>
                <pre class="json-data">{{ formatJsonData(taskInfo.nodeContent) }}</pre>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-primary" @click="handleSubmit" :disabled="loading">
          提交
        </button>
        <button class="btn btn-warning" @click="showForwardModal" :disabled="loading">
          转交
        </button>
        <button class="btn btn-default" @click="handleClose">关闭</button>
      </div>
    </div>
  </div>

<!-- 转交选择审批人模态框 -->
<div v-if="forwardModalVisible" class="modal-overlay" @click="cancelForward">
  <div class="modal-container modal-sm" @click.stop>
    <div class="modal-header">
      <h3>选择转交人</h3>
      <button class="close-btn" @click="cancelForward">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <line x1="18" y1="6" x2="6" y2="18"></line>
          <line x1="6" y1="6" x2="18" y2="18"></line>
        </svg>
      </button>
    </div>
    
    <div class="modal-body">
      <!-- 错误信息 -->
      <div v-if="forwardError" class="error-message">
        {{ forwardError }}
      </div>
      
      <!-- 加载状态 -->
      <div v-if="forwardLoading" class="loading-state">
        <div class="loading-spinner"></div>
        <p>加载中...</p>
      </div>
      
      <div v-else>
        <div class="form-group">
          <label for="approver-search-select" class="form-label">请选择转交人：</label>
          <!-- 统一的搜索下拉选择框 -->
          <div class="searchable-dropdown" ref="searchableDropdownRef">
            <div class="dropdown-input-wrapper">
              <input 
                type="text" 
                id="approver-search-select"
                v-model="searchTerm"
                placeholder="搜索用户..."
                class="form-control dropdown-input"
                @focus="showDropdown = true"
                @input="showDropdown = true"
              >
              <button 
                type="button"
                class="dropdown-toggle"
                @click="showDropdown = !showDropdown"
              >
                <span class="dropdown-arrow"></span>
              </button>
            </div>
            <!-- 下拉菜单 -->
            <div 
              v-if="showDropdown && !forwardLoading"
              class="dropdown-menu"
            >
              <div 
                v-for="user in getFilteredUsers()"
                :key="user.userId"
                class="dropdown-item"
                :class="{ 'active': selectedApprover.newApproverId === user.userId }"
                @click="selectUser(user)"
              >
                {{ user.userName }}
              </div>
              <div v-if="getFilteredUsers().length === 0" class="dropdown-empty">
                未找到匹配的用户
              </div>
            </div>
            <!-- 加载状态 -->
            <div v-if="showDropdown && forwardLoading" class="dropdown-loading">
              <div class="loading-spinner-small"></div>
              <span>加载中...</span>
            </div>
          </div>
        </div>
        
        <div class="form-group">
          <label for="forward-comment" class="form-label">转交备注：</label>
          <textarea 
            id="forward-comment"
            class="form-control comment-textarea"
            v-model="commentText"
            placeholder="请输入转交原因（可选）"
            rows="3"
          ></textarea>
        </div>
      </div>
    </div>
    
    <div class="modal-footer">
      <button class="btn btn-primary" @click="handleForward" :disabled="forwardLoading || !selectedApprover.newApproverId">
        确认转交
      </button>
      <button class="btn btn-default" @click="cancelForward" :disabled="forwardLoading">
        取消
      </button>
    </div>
  </div>
</div>
</template>


<script>
import { ref, onMounted, onUnmounted, watch, defineComponent, reactive, computed, markRaw } from 'vue';
import taskApprovalService from '../services/taskApprovalService';
import userService from '../services/userService';

// 引入Markdown解析库
let mdParser = null;

// 动态导入markdown-it
import('markdown-it').then(module => {
  mdParser = markRaw(module.default());
});

// 组件渲染器，根据type动态渲染不同的表单组件
const ComponentRenderer = defineComponent({
  name: 'ComponentRenderer',
  props: {
    component: {
      type: Object,
      required: true
    },
    modelValue: {
      type: [String, Number, Boolean, Array, Object, null],
      default: ''
    }
  },
  emits: ['update:model-value'],
  methods: {
    formatDate(dateStr) {
      if (!dateStr) return '-';
      try {
        const date = new Date(dateStr);
        return date.toLocaleString('zh-CN');
      } catch (error) {
        return dateStr;
      }
    },
    // 安全地解析JSON数据
    parseJSON(data) {
      if (!data) return {};
      if (typeof data === 'object') return data;
      try {
        return JSON.parse(data);
      } catch (error) {
        console.warn('Failed to parse JSON data:', error);
        return data;
      }
    },
    // 获取选项标签
    getOptionLabel(option) {
      if (typeof option === 'string') return option;
      return option.label || option.text || option.value || option;
    },
    // 获取选项值
    getOptionValue(option) {
      if (typeof option === 'string') return option;
      return option.value || option;
    },
    // 格式化JSON数据
    formatJsonData(jsonString) {
      try {
        if (typeof jsonString === 'string') {
          const parsed = JSON.parse(jsonString);
          return JSON.stringify(parsed, null, 2);
        } else {
          return JSON.stringify(jsonString, null, 2);
        }
      } catch (error) {
        console.error('解析JSON数据失败:', error);
        return jsonString;
      }
    },
    // 处理输入变化
    handleInput(event) {
      this.$emit('update:model-value', event.target.value);
    },
    // 处理多选变化
    handleCheckboxChange(event) {
      const value = event.target.value;
      let currentValue = this.modelValue || [];
      
      if (!Array.isArray(currentValue)) {
        currentValue = [];
      }
      
      if (event.target.checked) {
        if (!currentValue.includes(value)) {
          currentValue.push(value);
        }
      } else {
        currentValue = currentValue.filter(item => item !== value);
      }
      
      this.$emit('update:model-value', currentValue);
    },
    // 处理开关变化
    handleSwitchChange(event) {
      this.$emit('update:model-value', event.target.checked);
    },
    
    // 更新数组项
    updateArrayItem(index, event) {
      let currentValue = this.modelValue || [];
      
      if (!Array.isArray(currentValue)) {
        currentValue = [];
      }
      
      // 确保数组长度足够
      if (index >= currentValue.length) {
        // 填充空值直到达到index位置
        for (let i = currentValue.length; i <= index; i++) {
          currentValue[i] = '';
        }
      }
      
      // 更新指定索引的值
      currentValue[index] = event.target.value;
      
      this.$emit('update:model-value', [...currentValue]);
    },
    
    // 移除数组项
    removeArrayItem(index) {
      let currentValue = this.modelValue || [];
      
      if (!Array.isArray(currentValue)) {
        currentValue = [];
      }
      
      // 过滤掉指定索引的项
      const newValue = currentValue.filter((_, i) => i !== index);
      
      this.$emit('update:model-value', newValue);
    },
    
    // 添加新的数组项
    addArrayItem() {
      let currentValue = this.modelValue || [];
      
      if (!Array.isArray(currentValue)) {
        currentValue = [];
      }
      
      // 添加一个空字符串作为新项
      const newValue = [...currentValue, ''];
      
      this.$emit('update:model-value', newValue);
    }
  },
  template: `
    <div class="form-component-preview">
      <!-- 单行文本输入框 -->
      <div v-if="['input', 'text', 'email', 'password', 'number', 'url', 'tel', 'search'].includes(component.type)" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <input 
          :type="component.type === 'input' ? 'text' : component.type"
          :value="modelValue || ''" 
          @input="handleInput"
          class="preview-input"
          :placeholder="component.placeholder || ''"
          :maxlength="component.maxLength"
          :min="component.min"
          :max="component.max"
          :step="component.step"
          :readonly="component.readonly"
        >
      </div>
      
      <!-- 多行文本输入框 -->
      <div v-else-if="component.type === 'textarea'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <textarea 
          :value="modelValue || ''" 
          @input="handleInput"
          class="preview-textarea"
          :placeholder="component.placeholder || ''"
          :maxlength="component.maxLength"
          :readonly="component.readonly"
        ></textarea>
      </div>
      
      <!-- 下拉选择框 -->
      <div v-else-if="component.type === 'select'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <select @change="handleInput" class="preview-select" :disabled="component.disabled">
          <option value="">{{ component.placeholder || '请选择...' }}</option>
          <option 
            v-for="option in component.options" 
            :key="getOptionValue(option)" 
            :value="getOptionValue(option)" 
            :selected="modelValue === getOptionValue(option)"
          >{{ getOptionLabel(option) }}</option>
        </select>
      </div>
      
      <!-- 单选按钮组 -->
      <div v-else-if="component.type === 'radio'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <div class="radio-group">
          <label v-for="option in component.options" :key="getOptionValue(option)" class="radio-option">
            <input 
              type="radio" 
              :checked="modelValue === getOptionValue(option)" 
              :value="getOptionValue(option)"
              @change="handleInput"
              :disabled="component.disabled"
            >
            <span>{{ getOptionLabel(option) }}</span>
          </label>
        </div>
      </div>
      
      <!-- 复选框组 -->
      <div v-else-if="component.type === 'checkbox'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <div class="checkbox-group">
          <label v-for="option in component.options" :key="getOptionValue(option)" class="checkbox-option">
            <input 
              type="checkbox" 
              :checked="(modelValue || []).includes(getOptionValue(option))" 
              :value="getOptionValue(option)"
              @change="handleCheckboxChange"
              :disabled="component.disabled"
            >
            <span>{{ getOptionLabel(option) }}</span>
          </label>
        </div>
      </div>
      
      <!-- 日期时间选择器 -->
      <div v-else-if="['date', 'datetime', 'month', 'week', 'time'].includes(component.type)" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <input 
          :type="component.type === 'datetime' ? 'datetime-local' : component.type" 
          :value="modelValue"
          @input="handleInput"
          class="preview-date"
          :disabled="component.disabled"
        >
      </div>
      
      <!-- 范围选择器 -->
      <div v-else-if="component.type === 'range'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <div class="range-display">
          <span class="range-value">{{ modelValue || 0 }}</span>
          <input 
            type="range" 
            :min="component.min || 0" 
            :max="component.max || 100" 
            :step="component.step || 1" 
            :value="modelValue || 0" 
            @input="handleInput"
            class="preview-range"
            :disabled="component.disabled"
          >
        </div>
      </div>
      
      <!-- 颜色选择器 -->
      <div v-else-if="component.type === 'color'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <input 
          type="color" 
          :value="modelValue || '#000000'"
          @input="handleInput"
          class="preview-color"
          :disabled="component.disabled"
        >
        <span class="color-value">{{ modelValue || '#000000' }}</span>
      </div>
      
      <!-- 开关按钮 -->
      <div v-else-if="component.type === 'switch'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <label class="switch-control">
          <input 
            type="checkbox" 
            :checked="modelValue"
            @change="handleSwitchChange"
            :disabled="component.disabled"
          >
          <span class="switch-slider"></span>
        </label>
      </div>
      
      <!-- 文件上传 -->
      <div v-else-if="component.type === 'file'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <div class="file-display">
          <span v-if="Array.isArray(component.value)">
            {{ component.value.length }} 个文件
          </span>
          <span v-else-if="component.value">
            {{ component.value }}
          </span>
          <span v-else>无文件</span>
        </div>
      </div>
      
      <!-- 数组类型组件 -->
      <div v-else-if="component.type === 'array'" class="form-item array-container">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <div class="array-items">
          <div v-for="(item, index) in (modelValue || [])" :key="index" class="array-item">
            <input 
              type="text" 
              :value="item" 
              @input="updateArrayItem(index, $event)"
              class="array-item-input"
              :placeholder="component.placeholder || '输入内容'"
              :readonly="component.readonly"
            >
            <button 
              v-if="!component.readonly" 
              @click="removeArrayItem(index)"
              class="array-item-remove"
            >
              ×
            </button>
          </div>
          <button 
            v-if="!component.readonly" 
            @click="addArrayItem"
            class="array-add-item"
          >
            + 添加项
          </button>
          <div v-if="!(modelValue && modelValue.length) && component.readonly" class="no-array-items">
            空数组
          </div>
        </div>
      </div>
      
      <!-- 分隔线 -->
      <div v-else-if="component.type === 'divider'" class="divider-item">
        <div class="divider"></div>
        <div v-if="component.label" class="divider-label">{{ component.label }}</div>
      </div>
      
      <!-- 对象或JSON类型 -->
      <div v-else-if="component.type === 'object' || component.type === 'json'" class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <div class="json-container">
          <pre>{{ formatJsonData(modelValue) }}</pre>
        </div>
      </div>
      
      <!-- 隐藏字段 -->
      <div v-else-if="component.type === 'hidden'" class="form-item">
        <div class="hidden-field-info">
          <span class="field-name">{{ component.name }}</span>
          <span class="field-type">[隐藏字段]</span>
          <span class="field-value">{{ modelValue || '-' }}</span>
        </div>
      </div>
      
      <!-- 其他类型 -->
      <div v-else class="form-item">
        <label v-if="!component.hideLabel">{{ component.label || component.name }}：</label>
        <span v-if="Array.isArray(modelValue)" class="form-value array-display">
          {{ modelValue.join(', ') }}
        </span>
        <span v-else-if="typeof modelValue === 'object' && modelValue !== null" class="form-value">
          <pre class="json-data-small">{{ formatJsonData(modelValue) }}</pre>
        </span>
        <span v-else class="form-value">{{ modelValue || '-' }}</span>
      </div>
      
      <!-- 组件帮助信息 -->
      <div v-if="component.description" class="component-description">{{ component.description }}</div>
    </div>
  `
});

export default {
  name: 'TaskDataDetailModal',
  components: {
    ComponentRenderer
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    taskId: {
      type: [String, Number],
      required: true
    }
  },
  emits: ['close', 'submit', 'forward'],
  setup(props, { emit }) {
    const taskInfo = ref({});
    const loading = ref(false);
    const error = ref('');
    const formValues = reactive({});
    const originalFormValues = reactive({});
    const isFormModified = computed(() => {
      return JSON.stringify(formValues) !== JSON.stringify(originalFormValues);
    });
    
    // 转交相关状态
    const forwardModalVisible = ref(false);
    const users = ref([]);
    const selectedApprover = ref({ newApproverId: '', newApproverName: '' });
    const commentText = ref('');
    const forwardError = ref('');
    const forwardLoading = ref(false);
    const searchTerm = ref(''); // 搜索关键词

    // 获取任务数据
    const fetchTaskData = async () => {
      if (!props.visible || !props.taskId) return;
      
      loading.value = true;
      error.value = '';
      
      try {
        // 调用接口获取任务当前处理节点信息
        const response = await taskApprovalService.getCurrentProcessingNodeByTaskId(props.taskId);
        
        // 假设接口返回的数据结构包含taskTypeName、taskDescription等字段
        if (response && response.data) {
          // 直接使用返回的数据作为taskInfo
          taskInfo.value = response.data || {};
          
          // 初始化表单值
          initializeFormValues();
        }
      } catch (err) {
        console.error('获取任务数据失败:', err);
        error.value = '获取任务数据失败，请稍后重试';
        // 失败时使用默认模拟数据
        taskInfo.value = {
          id: String(props.taskId),
          taskTypeName: '未知任务类型',
          taskDescription: '暂无任务描述',
          statusText: '未知状态',
          approverName: '未知审批人',
          approverAuthId: '未知',
          flowName: '未知流程',
          nodeName: '未知节点',
          createTime: '-',
          // 模拟JSON数据
          rawData: { example: '这是模拟的原始数据' },
          extraFields: { example: '这是模拟的额外字段' },
          nodeContent: {
            formComponents: [
              {
                type: 'input',
                label: '用户名',
                name: 'username',
                value: 'testuser'
              },
              {
                type: 'select',
                label: '用户角色',
                name: 'role',
                value: 'admin',
                options: [
                  { value: 'admin', label: '管理员' },
                  { value: 'user', label: '普通用户' },
                  { value: 'guest', label: '访客' }
                ]
              },
              {
                type: 'radio',
                label: '性别',
                name: 'gender',
                value: 'male',
                options: [
                  { value: 'male', label: '男' },
                  { value: 'female', label: '女' }
                ]
              },
              {
                type: 'checkbox',
                label: '兴趣爱好',
                name: 'hobbies',
                value: ['reading', 'music'],
                options: [
                  { value: 'reading', label: '阅读' },
                  { value: 'music', label: '音乐' },
                  { value: 'sports', label: '运动' }
                ]
              }
            ]
          }
        };
        
        // 初始化表单值（即使是模拟数据也需要初始化）
        initializeFormValues();
      } finally {
        loading.value = false;
      }
    };

    // 格式化日期
    const formatDate = (dateStr) => {
      if (!dateStr) return '-';
      try {
        const date = new Date(dateStr);
        return date.toLocaleString('zh-CN');
      } catch (error) {
        return dateStr;
      }
    };

    // 解析 Markdown 内容
    const parseMarkdown = (markdown) => {
      if (!markdown || !mdParser) {
        return markdown || '';
      }
      try {
        // 预处理Markdown内容，确保标题#后面有空格（支持所有级别标题：#到######）
        let processedMarkdown = markdown.replace(/(^|\n)(#{1,6})(\S)/g, '$1$2 $3');
        
        // 调用配置好的markdown-it进行完整解析
        const result = mdParser.render(processedMarkdown);
        
        // 为解析结果添加统一的样式类，并去掉标题前的#符号
        // 注意：这里通过正则表达式处理HTML结果，移除标题标签内的#符号
        // 使用markdown-content类以支持列表缩进样式
        const styledResult = `<div class="markdown-content">${result.replace(/<(h[1-6])>(\s*#{1,6}\s*)(.*?)<\/\1>/g, '<$1>$3</$1>')}</div>`;
        
        return styledResult;
      } catch (error) {
        console.error('Markdown解析错误:', error);
        // 出错时返回原始文本，但添加基本样式
        return `<div class="markdown-content">${markdown}</div>`;
      }
    };

    // 处理关闭
    const handleClose = () => {
      emit('close');
    };

    // 初始化表单值
    const initializeFormValues = () => {
      const components = getParsedNodeContent(taskInfo.value.nodeContent || {});
      
      // 清空现有值
      Object.keys(formValues).forEach(key => delete formValues[key]);
      Object.keys(originalFormValues).forEach(key => delete originalFormValues[key]);
      
      // 初始化新值
      components.forEach((component, index) => {
        const fieldName = component.name || `field_${index}`;
        const value = component.value !== undefined ? component.value : '';
        
        // 深拷贝值，避免引用类型的比较问题
        if (typeof value === 'object' && value !== null) {
          formValues[fieldName] = JSON.parse(JSON.stringify(value));
          originalFormValues[fieldName] = JSON.parse(JSON.stringify(value));
        } else {
          formValues[fieldName] = value;
          originalFormValues[fieldName] = value;
        }
      });
    };

    // 更新表单值
    const updateFormValue = (fieldName, value) => {
      formValues[fieldName] = value;
    };

    // 处理提交
    const handleSubmit = async () => {
      if (loading.value) return;
      
      try {
        loading.value = true;
        error.value = '';
        
        // 准备审批任务的数据
        const approvalData = {
          taskApprovalStatusId: taskInfo.value.id || props.taskId, // 优先使用从接口获取的id，作为备用
          comment: JSON.stringify(formValues),
          // 判断是否有"是否通过"单选框组
          status: getStatusValue()
        };

        // 获取status值的函数
      function getStatusValue() {
        // 首先检查表单数据中是否有"是否通过"字段
        // 检查comment(JSON字符串)中的"是否通过"值
        try {
          const commentObj = formValues;
          // 查找是否有"是否通过"相关的字段
          const approvalFieldKey = Object.keys(commentObj).find(key => 
            key.includes('是否通过') || key.includes('审批结果') || key.includes('是否同意')
          );
          
          if (approvalFieldKey) {
            const approvalValue = commentObj[approvalFieldKey];
            console.log('通过字段:', approvalFieldKey, '值:', approvalValue);
            
            // 根据comment中的值设置status
            if (approvalValue === '1' || approvalValue === 1) {
              console.log('comment中是1，status设置为2');
              return 2;
            } else if (approvalValue === '2' || approvalValue === 2) {
              console.log('comment中是2，status设置为3');
              return 3;
            }
          }
        } catch (e) {
          console.error('解析comment失败:', e);
        }
        
        // 如果没有找到"是否通过"字段或解析失败，使用原始逻辑
        const components = getParsedNodeContent(taskInfo.nodeContent);
        const approvalComponent = components.find(comp => 
          comp.type === 'radio' && 
          comp.label && 
          (comp.label.includes('是否通过') || comp.label.includes('审批结果') || comp.label.includes('是否同意'))
        );
        
        // 如果有审批组件，根据表单值设置status
        if (approvalComponent) {
          const componentName = approvalComponent.name || `field_${components.indexOf(approvalComponent)}`;
          const formValue = formValues[componentName];
          console.log('审批组件:', approvalComponent, '组件名称:', componentName, '表单值:', formValue);
          
          // 处理各种可能的通过/不通过值
          if (formValue === '通过' || formValue === 1 || formValue === true || 
              formValue === '同意' || formValue === 'yes' || formValue === 'pass') {
            return 2;
          } else if (formValue === '不通过' || formValue === 0 || formValue === false || 
                    formValue === '拒绝' || formValue === 'no' || formValue === 'fail') {
            return 3;
          }
        }
        
        // 如果没有审批组件或值无法确定，默认传2
        console.log('未找到审批组件或值无法确定，默认传2');
        return 2;
      };
        
        // 调用审批任务接口
        await taskApprovalService.approveTask(approvalData);
        
        // 提交成功后更新原始值
        Object.keys(formValues).forEach(key => {
          if (typeof formValues[key] === 'object' && formValues[key] !== null) {
            originalFormValues[key] = JSON.parse(JSON.stringify(formValues[key]));
          } else {
            originalFormValues[key] = formValues[key];
          }
        });
        
        // 触发成功事件
        emit('submit', formValues);
        
        // 提示成功信息
        console.log('审批任务提交成功');
        // 可以在这里添加UI提示，如成功消息弹窗等
      } catch (err) {
        console.error('审批任务提交失败:', err);
        error.value = '审批任务提交失败，请稍后重试';
      } finally {
        loading.value = false;
      }
    };

    // 处理遮罩层点击
    const handleOverlayClick = () => {
      handleClose();
    };

    // 解析节点内容 - 增强版，支持更复杂的JSON格式
    const getParsedNodeContent = (nodeContent) => {
      try {
        if (!nodeContent) return [];
        
        // 处理字符串类型的内容
        if (typeof nodeContent === 'string') {
          // 尝试直接解析
          try {
            // 清理字符串，处理可能的JSON字符串周围的多余字符
            const cleanedString = nodeContent.trim()
              .replace(/^\s*'([\s\S]*)'\s*$/, '$1') // 移除单引号
              .replace(/^\s*"([\s\S]*)"\s*$/, '$1') // 移除双引号
              .replace(/^\s*`([\s\S]*)`\s*$/, '$1') // 移除反引号
              .replace(/\\"/g, '"') // 处理转义的双引号
              .replace(/\\'/g, "'"); // 处理转义的单引号
            
            const parsed = JSON.parse(cleanedString);
            
            // 处理多种可能的数据结构
            if (Array.isArray(parsed)) {
              // 如果是数组，直接返回
              return parsed;
            } else if (typeof parsed === 'object') {
              // 如果是对象，检查是否有components或fields字段
              if (parsed.components && Array.isArray(parsed.components)) {
                return parsed.components;
              } else if (parsed.fields && Array.isArray(parsed.fields)) {
                return parsed.fields;
              } else if (parsed.formComponents && Array.isArray(parsed.formComponents)) {
                return parsed.formComponents;
              } else {
                // 返回对象的所有值（过滤掉非对象类型）
                return Object.values(parsed).filter(val => typeof val === 'object');
              }
            }
            return [];
          } catch (parseError) {
            console.warn('直接解析失败，尝试其他解析方法:', parseError);
            
            // 尝试作为简单文本处理
            return [{ id: 'raw-content', type: 'text', label: '原始内容', value: nodeContent }];
          }
        } 
        // 处理对象类型的内容
        else if (typeof nodeContent === 'object') {
          if (Array.isArray(nodeContent)) {
            return nodeContent;
          } else if (nodeContent.components && Array.isArray(nodeContent.components)) {
            return nodeContent.components;
          } else if (nodeContent.fields && Array.isArray(nodeContent.fields)) {
            return nodeContent.fields;
          } else if (nodeContent.formComponents && Array.isArray(nodeContent.formComponents)) {
            return nodeContent.formComponents;
          } else {
            return Object.values(nodeContent).filter(val => typeof val === 'object');
          }
        }
        return [];
      } catch (error) {
        console.error('解析节点内容失败:', error);
        // 提供更好的错误回退机制
        return [{
          id: 'error-content', 
          type: 'text', 
          label: '解析错误', 
          value: '无法解析表单内容，原始数据可能格式不正确',
          description: '请检查原始数据格式是否符合JSON标准'
        }];
      }
    };

    // 获取组件值
    const getComponentValue = (component) => {
      // 从组件对象中直接获取value属性
      if (component.value !== undefined) {
        return component.value;
      }
      
      // 如果有defaultValue且没有value，则使用defaultValue
      if (component.defaultValue !== undefined) {
        return component.defaultValue;
      }
      
      return '';
    };

    // 获取组件类型显示名称
    const getComponentTypeDisplay = (type) => {
      const typeMap = {
        'input': '单行文本输入框',
        'textarea': '多行文本输入框',
        'select': '下拉选择框',
        'radio': '单选按钮',
        'checkbox': '复选框',
        'date': '日期选择器',
        'number': '数字输入框',
        'email': '邮箱输入框',
        'password': '密码输入框',
        'file': '文件上传',
        'switch': '开关按钮',
        'range': '范围选择器',
        'color': '颜色选择器',
        'datetime': '日期时间选择器',
        'time': '时间选择器',
        'month': '月份选择器',
        'week': '周选择器',
        'url': 'URL输入框',
        'tel': '电话输入框',
        'search': '搜索框',
        'array': '数组类型',
        'object': '对象类型',
        'json': 'JSON数据',
        'divider': '分隔线',
        'text': '文本',
        'hidden': '隐藏字段'
      };
      return typeMap[type] || type || '未知类型';
    };

    // 检查组件是否有额外属性
    const hasExtraProperties = (component) => {
      return component.placeholder || 
             component.defaultValue !== undefined || 
             component.maxLength !== undefined || 
             component.min !== undefined || 
             component.max !== undefined || 
             (component.options && component.options.length > 0);
    };

    // 格式JSON数据
    const formatJsonData = (jsonString) => {
      try {
        if (typeof jsonString === 'string') {
          const parsed = JSON.parse(jsonString);
          return JSON.stringify(parsed, null, 2);
        } else {
          return JSON.stringify(jsonString, null, 2);
        }
      } catch (error) {
        console.error('解析JSON数据失败:', error);
        return jsonString;
      }
    };

    // 监听visible和taskId的变化，重新获取数据
    watch([() => props.visible, () => props.taskId], () => {
      if (props.visible) {
        fetchTaskData();
      }
    }, { immediate: true });

    // 获取所有用户
    const fetchUsers = async () => {
      try {
        forwardLoading.value = true;
        forwardError.value = '';
        const response = await userService.getUsers();
        if (response && response.data) {
          users.value = response.data;
          // 清空搜索关键词
          searchTerm.value = '';
        }
      } catch (err) {
        console.error('获取用户列表失败:', err);
        forwardError.value = '获取用户列表失败，请稍后重试';
      } finally {
        forwardLoading.value = false;
      }
    };

    // 控制下拉框显示
    const showDropdown = ref(false);
    // 搜索下拉框引用
    const searchableDropdownRef = ref(null);

    // 选择用户
    const selectUser = (user) => {
      selectedApprover.value.newApproverId = user.userId;
      selectedApprover.value.newApproverName = user.userName;
      searchTerm.value = user.userName;
      showDropdown.value = false;
    };
    
    // 根据搜索词过滤用户
    const getFilteredUsers = () => {
      if (!searchTerm.value) {
        return users.value;
      }
      const term = searchTerm.value.toLowerCase();
      return users.value.filter(user => 
        user.userName.toLowerCase().includes(term) || 
        (user.userId && user.userId.toString().toLowerCase().includes(term))
      );
    };

    // 显示转交模态框
    const showForwardModal = async () => {
      await fetchUsers();
      forwardModalVisible.value = true;
    };

    // 处理转交
    const handleForward = async () => {
      if (!selectedApprover.value.newApproverId) {
        forwardError.value = '请选择转交人';
        return;
      }

      try {
        forwardLoading.value = true;
        forwardError.value = '';
        
        // 构建转交数据
        const forwardData = {
          taskApprovalStatusId: taskInfo.value.id || props.taskId, // 使用任务审批状态ID或任务ID作为备选
          newApproverId: selectedApprover.value.newApproverId,
          newApproverName: selectedApprover.value.newApproverName,
          comment: commentText.value,
          currentApproverId: taskInfo.value.approverId,
          currentApproverName: taskInfo.value.approverName
        };
        
        console.log('准备转交任务，数据:', forwardData);
        
        // 调用转交任务接口
        await taskApprovalService.forwardTask(forwardData);
        
        // 关闭模态框
        closeForwardModal();
        
        // 触发成功事件
        emit('forward', forwardData);
        
        // 提示成功信息
        console.log('任务转交成功');
        // 可以在这里添加UI提示，如成功消息弹窗等
      } catch (err) {
        console.error('转交任务失败:', err);
        forwardError.value = '转交任务失败，请稍后重试';
      } finally {
        forwardLoading.value = false;
      }
    };

    // 取消转交
    const cancelForward = () => {
      closeForwardModal();
    };

    // 关闭转交模态框
    const closeForwardModal = () => {
      forwardModalVisible.value = false;
      selectedApprover.value = { newApproverId: '', newApproverName: '' };
      commentText.value = '';
      forwardError.value = '';
      searchTerm.value = ''; // 清空搜索关键词
      showDropdown.value = false; // 关闭下拉框
    };

    // 点击外部关闭下拉框
    onMounted(() => {
      const handleClickOutside = (event) => {
        if (searchableDropdownRef.value && !searchableDropdownRef.value.contains(event.target)) {
          showDropdown.value = false;
        }
      };
      
      document.addEventListener('mousedown', handleClickOutside);
      
      onUnmounted(() => {
        document.removeEventListener('mousedown', handleClickOutside);
      });
    });

    // 监听审批人选择变化
    watch(() => selectedApprover.value.newApproverId, (newValue) => {
      if (newValue) {
        const selectedUser = users.value.find(user => user.userId === newValue);
        if (selectedUser) {
          selectedApprover.value.newApproverName = selectedUser.userName || '';
        }
      }
    });

    return {
      taskInfo,
      loading,
      error,
      formValues,
      isFormModified,
      formatDate,
      parseMarkdown,
      handleClose,
      handleOverlayClick,
      handleSubmit,
      updateFormValue,
      getParsedNodeContent,
      getComponentValue,
      getComponentTypeDisplay,
      hasExtraProperties,
      formatJsonData,
      // 转交相关
      forwardModalVisible,
      users,
      selectedApprover,
      commentText,
      forwardError,
      forwardLoading,
      searchTerm,
      showDropdown,
      searchableDropdownRef,
      getFilteredUsers,
      selectUser,
      showForwardModal,
      handleForward,
      cancelForward,
      // 安全解析原始数据
      parseRawData() {
        if (!taskInfo.value.rawData) return {};
        if (typeof taskInfo.value.rawData === 'object') return taskInfo.value.rawData;
        try {
          return JSON.parse(taskInfo.value.rawData);
        } catch (error) {
          console.warn('Failed to parse rawData:', error);
          return taskInfo.value.rawData;
        }
      },
      // 安全解析额外字段
      parseExtraFields() {
        if (!taskInfo.value.extraFields) return {};
        if (typeof taskInfo.value.extraFields === 'object') return taskInfo.value.extraFields;
        try {
          return JSON.parse(taskInfo.value.extraFields);
        } catch (error) {
          console.warn('Failed to parse extraFields:', error);
          return taskInfo.value.extraFields;
        }
      }
    };
  }
};
</script>

<style scoped>
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.2s ease-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.modal-container {
  background-color: white;
  border-radius: 8px;
  width: 90%;
  max-width: 900px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
  from {
    transform: translateY(-20px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid #e8e8e8;
}

.modal-header h3 {
  margin: 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
}

.close-btn {
  background: none;
  border: none;
  color: #999;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  transition: all 0.3s;
}

.close-btn:hover {
  background-color: #f5f5f5;
  color: #666;
}

.modal-body {
  padding: 20px;
  overflow-y: auto;
  flex: 1;
}

/* 加载状态样式 */
.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 300px;
  color: #666;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #40a9ff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 错误状态样式 */
.error-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 300px;
  color: #ff4d4f;
  text-align: center;
}

.error-state p {
  margin-top: 16px;
  font-size: 14px;
  line-height: 1.5;
}

/* 无数据状态样式 */
.no-data {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  color: #999;
  font-size: 14px;
}

/* 任务基本信息样式 */
.task-basic-info {
  margin-bottom: 24px;
  background-color: #fafafa;
  padding: 16px;
  border-radius: 6px;
  border: 1px solid #e8e8e8;
}

.task-basic-info h4 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.task-type-name {
  font-size: 16px;
  font-weight: 500;
  color: #1890ff;
  margin-bottom: 16px;
  padding: 8px 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 任务描述样式 */
.task-description {
  background-color: #fff;
  padding: 16px;
  border-radius: 4px;
  margin-bottom: 16px;
  border: 1px solid #e8e8e8;
  line-height: 1.6;
}

/* Markdown 渲染样式 - 支持直接渲染的元素 */
.task-description h1,
.task-description h2,
.task-description h3,
.task-description h4,
.task-description h5,
.task-description h6 {
  margin-top: 1.5em;
  margin-bottom: 0.5em;
  font-weight: 600;
  color: #333;
}

.task-description h1 { font-size: 1.8em; }
.task-description h2 { font-size: 1.6em; }
.task-description h3 { font-size: 1.4em; }
.task-description h4 { font-size: 1.2em; }
.task-description h5 { font-size: 1.1em; }
.task-description h6 { font-size: 1em; color: #666; }

.task-description p {
  margin-bottom: 1em;
}

.task-description strong {
  font-weight: 600;
  color: #333;
}

.task-description em {
  font-style: italic;
  color: #666;
}

.task-description code {
  background-color: #f5f5f5;
  padding: 0.2em 0.4em;
  border-radius: 3px;
  font-family: 'Courier New', monospace;
  font-size: 0.9em;
  color: #e96900;
}

.task-description pre {
  background-color: #f5f5f5;
  padding: 1em;
  border-radius: 4px;
  overflow-x: auto;
  margin-bottom: 1em;
}

.task-description pre code {
  background: none;
  padding: 0;
  color: #333;
}

.task-description ul,
.task-description ol {
  margin-left: 1.5em;
  margin-bottom: 1em;
}

.task-description li {
  margin-bottom: 0.3em;
}

.task-description a {
  color: #1890ff;
  text-decoration: none;
}

.task-description a:hover {
  text-decoration: underline;
}

.task-description img {
  max-width: 100%;
  border-radius: 4px;
}

.task-description blockquote {
  border-left: 4px solid #d9d9d9;
  padding-left: 1em;
  margin-left: 0;
  margin-right: 0;
  color: #666;
  font-style: italic;
}

.task-description table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1em;
}

.task-description th {
  background-color: #fafafa;
  padding: 0.5em;
  text-align: left;
  border: 1px solid #e8e8e8;
  font-weight: 600;
}

.task-description td {
  padding: 0.5em;
  border: 1px solid #e8e8e8;
}

/* .markdown-text 类的样式 */
.markdown-text {
  line-height: 1.6;
}

.markdown-text h1,
.markdown-text h2,
.markdown-text h3,
.markdown-text h4,
.markdown-text h5,
.markdown-text h6 {
  margin-top: 1.5em;
  margin-bottom: 0.5em;
  font-weight: 600;
  color: #333;
}

.markdown-text h1 { font-size: 1.8em; }
.markdown-text h2 { font-size: 1.6em; }
.markdown-text h3 { font-size: 1.4em; }
.markdown-text h4 { font-size: 1.2em; }
.markdown-text h5 { font-size: 1.1em; }
.markdown-text h6 { font-size: 1em; color: #666; }

.markdown-text p {
  margin-bottom: 1em;
}

.markdown-text strong {
  font-weight: 600;
  color: #333;
}

.markdown-text em {
  font-style: italic;
  color: #666;
}

.markdown-text code {
  background-color: #f5f5f5;
  padding: 0.2em 0.4em;
  border-radius: 3px;
  font-family: 'Courier New', monospace;
  font-size: 0.9em;
  color: #e96900;
}

.markdown-text pre {
  background-color: #f5f5f5;
  padding: 1em;
  border-radius: 4px;
  overflow-x: auto;
  margin-bottom: 1em;
}

.markdown-text pre code {
  background: none;
  padding: 0;
  color: #333;
}

.markdown-text ul,
.markdown-text ol {
  margin-left: 1.5em;
  margin-bottom: 1em;
}

.markdown-text li {
  margin-bottom: 0.3em;
}

.markdown-text a {
  color: #1890ff;
  text-decoration: none;
}

.markdown-text a:hover {
  text-decoration: underline;
}

.markdown-text img {
  max-width: 100%;
  border-radius: 4px;
}

.markdown-text blockquote {
  border-left: 4px solid #d9d9d9;
  padding-left: 1em;
  margin-left: 0;
  margin-right: 0;
  color: #666;
  font-style: italic;
}

.markdown-text table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1em;
}

.markdown-text th {
  background-color: #fafafa;
  padding: 0.5em;
  text-align: left;
  border: 1px solid #e8e8e8;
  font-weight: 600;
}

.markdown-text td {
  padding: 0.5em;
  border: 1px solid #e8e8e8;
}

/* 状态信息样式 */
.task-status-info {
  margin-bottom: 24px;
  background-color: #fafafa;
  padding: 16px;
  border-radius: 6px;
  border: 1px solid #e8e8e8;
}

.task-status-info h4 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 12px;
}

.info-item {
  display: flex;
  flex-direction: column;
}

.info-label {
  font-size: 12px;
  color: #999;
  margin-bottom: 4px;
}

.info-value {
  font-size: 14px;
  color: #333;
}

.status-badge {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
}

.status-pending {
  background-color: #fff7e6;
  color: #fa8c16;
}

.status-processing {
  background-color: #e6f7ff;
  color: #1890ff;
}

.status-completed {
  background-color: #f6ffed;
  color: #52c41a;
}

.status-cancelled {
  background-color: #fff2f0;
  color: #ff4d4f;
}

.status-unknown {
  background-color: #f5f5f5;
  color: #999;
}

/* JSON数据样式 */
.task-json-data {
  margin-bottom: 24px;
  background-color: #fafafa;
  padding: 16px;
  border-radius: 6px;
  border: 1px solid #e8e8e8;
}

.task-json-data h4 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.json-container {
  background-color: #fff;
  padding: 16px;
  border-radius: 4px;
  overflow-x: auto;
  border: 1px solid #e8e8e8;
}

.json-container pre {
  margin: 0;
  font-size: 12px;
  font-family: 'Courier New', Courier, monospace;
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* 节点内容样式 */
.task-node-content {
  margin-bottom: 24px;
  background-color: #fafafa;
  padding: 16px;
  border-radius: 6px;
  border: 1px solid #e8e8e8;
}

.task-node-content h4 {
  margin: 0 0 16px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.node-content-form {
  background-color: #fff;
  padding: 20px;
  border-radius: 4px;
  border: 1px solid #e8e8e8;
}

/* 表单设计器组件样式 */
.form-designer-components {
  width: 100%;
}

/* 搜索下拉框容器样式 */
.searchable-select-container {
  position: relative;
}

/* 搜索框样式 */
.search-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px 4px 0 0;
  font-size: 14px;
  background-color: #fff;
  transition: border-color 0.3s, box-shadow 0.3s;
  outline: none;
}

.search-input:hover {
  border-color: #40a9ff;
}

.search-input:focus {
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(64, 169, 255, 0.2);
}

/* 搜索后下拉框样式 */
.searchable-select-container select {
  border-radius: 0 0 4px 4px;
  margin-top: -1px; /* 移除搜索框和下拉框之间的间距 */
}

.form-designer-info {
  margin-bottom: 16px;
}

.section-description {
  color: #666;
  font-size: 14px;
  margin: 0;
}

/* 表单组件列表样式 */
.form-components-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.form-component-card {
  background-color: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  padding: 16px;
  transition: all 0.3s;
}

.form-component-card:hover {
  border-color: #40a9ff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 组件头部样式 */
.component-header {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid #f0f0f0;
}

.component-icon-wrapper {
  margin-right: 12px;
}

.component-icon {
  font-size: 20px;
}

.component-title-info {
  flex: 1;
}

.component-name {
  margin: 0 0 4px 0;
  font-size: 14px;
  font-weight: 500;
  color: #333;
}

.component-type-badge {
  display: inline-block;
  padding: 2px 8px;
  background-color: #f0f0f0;
  border-radius: 10px;
  font-size: 12px;
  color: #666;
}

.component-required-badge {
  background-color: #fff2f0;
  border-radius: 10px;
  padding: 2px 8px;
}

.required-text {
  font-size: 12px;
  color: #ff4d4f;
  font-weight: 500;
}

/* 组件主体样式 */
.component-body {
  font-size: 14px;
}

.component-label {
  margin-bottom: 8px;
  color: #666;
}

.component-value {
  margin-bottom: 12px;
}

.read-only-value {
  margin-top: 4px;
  padding: 8px;
  background-color: #fafafa;
  border-radius: 4px;
  word-break: break-word;
}

/* 组件属性样式 */
.component-properties {
  margin-bottom: 12px;
  padding: 12px;
  background-color: #fafafa;
  border-radius: 4px;
}

.property-item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
}

.property-item:last-child {
  margin-bottom: 0;
}

.property-label {
  color: #666;
  font-size: 13px;
}

.property-value {
  color: #333;
  font-size: 13px;
  font-weight: 500;
}

.required-yes {
  color: #52c41a;
}

.required-no {
  color: #999;
}

/* 组件特殊属性样式 */
.component-extra-props {
  padding: 12px;
  background-color: #fafafa;
  border-radius: 4px;
}

.component-extra-props h6 {
  margin: 0 0 8px 0;
  color: #333;
  font-size: 13px;
  font-weight: 500;
}

.extra-props-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.extra-prop {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  font-size: 12px;
}

.prop-name {
  color: #666;
  margin-right: 4px;
}

.prop-value {
  color: #333;
  font-weight: 500;
}

.options-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 4px;
}

.option-item {
  display: inline-block;
  padding: 2px 6px;
  background-color: #e6f7ff;
  color: #1890ff;
  border-radius: 4px;
  font-size: 11px;
}

/* 组件渲染器样式 */
.form-component-preview {
  width: 100%;
}

.form-item {
  margin-bottom: 16px;
  padding: 12px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border: 1px solid #e9ecef;
  transition: all 0.3s;
}

.form-item:hover {
  background-color: #fff;
  border-color: #40a9ff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.form-item:last-child {
  margin-bottom: 0;
}

.form-item label {
  display: block;
  font-size: 14px;
  color: #333;
  margin-bottom: 8px;
  font-weight: 500;
}

.preview-input,
.preview-textarea,
.preview-select,
.preview-date,
.preview-datetime {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 14px;
  background-color: #fff;
  transition: border-color 0.3s, box-shadow 0.3s;
  outline: none;
}

.preview-input:hover,
.preview-textarea:hover,
.preview-select:hover,
.preview-date:hover,
.preview-datetime:hover {
  border-color: #40a9ff;
}

.preview-input:focus,
.preview-textarea:focus,
.preview-select:focus,
.preview-date:focus,
.preview-datetime:focus {
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(64, 169, 255, 0.2);
}

.preview-textarea {
  min-height: 80px;
  resize: vertical;
}

.checkbox-group,
.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.checkbox-group label,
.radio-group label {
  display: flex;
  align-items: center;
  font-weight: normal;
  margin-bottom: 0;
  cursor: pointer;
}

.checkbox-group input[type="checkbox"],
.radio-group input[type="radio"] {
  margin-right: 6px;
  cursor: pointer;
}

.array-container {
  border: 1px dashed #d9d9d9;
  padding: 12px;
  border-radius: 4px;
  background-color: #fff;
}

.array-items {
  margin-top: 8px;
}

.array-item {
  display: inline-flex;
  align-items: center;
  margin-right: 8px;
  margin-bottom: 8px;
  border-radius: 4px;
  font-size: 13px;
}

.array-item-input {
  padding: 6px 10px;
  border: 1px solid #d9d9d9;
  border-radius: 4px 0 0 4px;
  font-size: 13px;
  outline: none;
  background-color: #fff;
  min-width: 120px;
}

.array-item-input:hover {
  border-color: #40a9ff;
}

.array-item-input:focus {
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(64, 169, 255, 0.2);
}

.array-item-remove {
  background-color: #ff4d4f;
  color: white;
  border: none;
  border-radius: 0 4px 4px 0;
  padding: 6px 8px;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  transition: background-color 0.3s;
}

.array-item-remove:hover {
  background-color: #ff7875;
}

.array-add-item {
  background-color: #52c41a;
  color: white;
  border: none;
  border-radius: 4px;
  padding: 6px 12px;
  margin-top: 8px;
  cursor: pointer;
  font-size: 13px;
  transition: background-color 0.3s;
}

.array-add-item:hover {
  background-color: #73d13d;
}

.no-array-items {
  color: #999;
  font-size: 13px;
  font-style: italic;
}

.divider-item {
  margin: 16px 0;
  text-align: center;
}

.divider {
  height: 1px;
  background-color: #e8e8e8;
  margin: 8px 0;
}

.divider-label {
  font-size: 12px;
  color: #999;
  font-weight: 500;
}

.form-value {
  font-size: 14px;
  color: #333;
  word-break: break-word;
}

.array-display {
  display: inline-block;
  padding: 8px;
  background-color: #e6f7ff;
  border-radius: 4px;
  color: #1890ff;
}

/* 范围选择器样式 */
.range-display {
  display: flex;
  align-items: center;
  gap: 12px;
}

.range-value {
  min-width: 40px;
  text-align: center;
  font-weight: 500;
  color: #1890ff;
}

.preview-range {
  flex: 1;
  cursor: pointer;
}

/* 颜色选择器样式 */
.preview-color {
  width: 60px;
  height: 40px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  cursor: pointer;
  transition: border-color 0.3s;
  margin-right: 12px;
}

.preview-color:hover {
  border-color: #40a9ff;
}

.color-value {
  font-family: 'Courier New', Courier, monospace;
  color: #333;
  font-weight: 500;
}

/* 文件显示样式 */
.file-display {
  padding: 8px;
  background-color: #fafafa;
  border-radius: 4px;
  color: #666;
}

/* 开关按钮样式 */
.switch-control {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 22px;
  cursor: pointer;
}

.switch-control input {
  opacity: 0;
  width: 0;
  height: 0;
}

.switch-slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: .4s;
  border-radius: 22px;
}

.switch-slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 2px;
  bottom: 2px;
  background-color: white;
  transition: .4s;
  border-radius: 50%;
}

input:checked + .switch-slider {
  background-color: #1890ff;
}

input:checked + .switch-slider:before {
  transform: translateX(22px);
}

/* 回退显示样式 */
.fallback-json-display {
  background-color: #fff2f0;
  padding: 16px;
  border-radius: 4px;
  border: 1px solid #ffccc7;
}

.fallback-info {
  color: #ff4d4f;
  margin: 0 0 12px 0;
  font-size: 14px;
}

/* JSON小数据样式 */
.json-data-small {
  margin: 0;
  font-size: 11px;
  font-family: 'Courier New', Courier, monospace;
  white-space: pre-wrap;
  word-wrap: break-word;
  background-color: #f5f5f5;
  padding: 8px;
  border-radius: 4px;
}

/* 统一的搜索下拉选择框样式 */
    /* 搜索下拉选择框样式 - 统一主题风格 */
    .searchable-dropdown {
      position: relative;
      width: 100%;
    }
    
    .dropdown-input-wrapper {
      position: relative;
      width: 100%;
    }
    
    .dropdown-input {
      width: 100%;
      padding: var(--spacing-md);
      padding-right: calc(var(--spacing-xl) + 8px);
      border: 1px solid var(--border-base);
      border-radius: var(--border-radius-base);
      font-size: var(--font-size-base);
      font-family: inherit;
      transition: all 0.3s ease;
      background-color: var(--bg-white);
      color: var(--text-primary);
    }
    
    .dropdown-input:focus {
      outline: none;
      border-color: var(--primary-color);
      box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.2);
    }
    
    .dropdown-input::placeholder {
      color: var(--text-placeholder);
    }
    
    .dropdown-toggle {
      position: absolute;
      top: 0;
      right: 0;
      height: 100%;
      width: 40px;
      border: none;
      background-color: transparent;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: background-color 0.2s;
      border-radius: 0 var(--border-radius-base) var(--border-radius-base) 0;
    }
    
    .dropdown-toggle:hover {
      background-color: var(--bg-hover);
    }
    
    .dropdown-arrow {
      display: inline-block;
      width: 0;
      height: 0;
      border-left: 4px solid transparent;
      border-right: 4px solid transparent;
      border-top: 6px solid var(--text-secondary);
      transition: transform 0.2s;
    }
    
    .dropdown-menu {
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      max-height: 200px;
      overflow-y: auto;
      border: 1px solid var(--border-base);
      border-radius: var(--border-radius-base);
      background-color: var(--bg-white);
      margin-top: var(--spacing-xs);
      z-index: 1000;
      box-shadow: var(--shadow-md);
      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }
    
    .dropdown-item {
      padding: var(--spacing-md) var(--spacing-lg);
      cursor: pointer;
      transition: all 0.3s ease;
      color: var(--text-regular);
      font-size: var(--font-size-base);
    }
    
    .dropdown-item:hover {
      background-color: var(--bg-hover);
      color: var(--text-primary);
    }
    
    .dropdown-item.active {
      background-color: var(--bg-active);
      color: var(--primary-color);
      font-weight: 500;
    }
    
    .dropdown-empty {
      padding: var(--spacing-lg);
      color: var(--text-secondary);
      text-align: center;
      font-size: var(--font-size-base);
    }
    
    .dropdown-loading {
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      padding: var(--spacing-lg);
      border: 1px solid var(--border-base);
      border-radius: var(--border-radius-base);
      background-color: var(--bg-white);
      margin-top: var(--spacing-xs);
      z-index: 1000;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: var(--spacing-sm);
      color: var(--text-secondary);
      font-size: var(--font-size-base);
      box-shadow: var(--shadow-md);
    }
    
    .loading-spinner-small {
      width: 16px;
      height: 16px;
      border: 2px solid rgba(0, 102, 204, 0.1);
      border-top: 2px solid var(--primary-color);
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }
    
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
    
    /* 模态框底部样式 */
    .modal-footer {
      padding: var(--spacing-lg) var(--spacing-xl);
      border-top: 1px solid var(--border-base);
      display: flex;
      justify-content: flex-end;
      gap: var(--spacing-md);
      background-color: var(--bg-white);
    }

    /* 按钮样式 - 与系统主题保持一致 */
    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: var(--spacing-md) var(--spacing-lg);
      border: none;
      border-radius: var(--border-radius-base);
      font-size: var(--font-size-base);
      font-weight: 500;
      line-height: 1;
      text-align: center;
      text-decoration: none;
      cursor: pointer;
      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      user-select: none;
      outline: none;
      box-shadow: var(--shadow-sm);
      position: relative;
      overflow: hidden;
      gap: var(--spacing-xs);
      min-width: 80px;
      letter-spacing: 0.02em;
    }

    /* 按钮悬停光效 */
    .btn::before {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 50%);
      transform: translateX(-100%);
      transition: transform 0.3s ease;
    }

    .btn:hover::before {
      transform: translateX(100%);
    }

    /* 主按钮样式 */
    .btn-primary {
      background-color: var(--primary-color);
      color: #ffffff;
    }

    .btn-primary:hover {
      background-color: var(--primary-hover);
      box-shadow: var(--shadow-md);
      transform: translateY(-1px);
    }

    .btn-primary:active {
      background-color: var(--primary-active);
      transform: translateY(0);
    }

    .btn-primary:focus {
      box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.2);
    }

    .btn-primary:disabled {
      background-color: #c7d2fe;
      cursor: not-allowed;
      transform: none;
      opacity: 0.6;
    }

    /* 默认按钮样式 */
    .btn-default {
      background-color: var(--bg-white);
      color: var(--text-regular);
      border: 1px solid var(--border-light);
    }

    .btn-default:hover {
      color: var(--primary-color);
      border-color: var(--primary-color);
      box-shadow: var(--shadow-md);
    }

    /* 表单组样式 */
    .form-group {
      margin-bottom: var(--spacing-xl);
      transition: all 0.3s ease;
    }

    .form-group:hover {
      transform: translateX(2px);
    }

    /* 表单标签样式 */
    .form-label {
      display: block;
      margin-bottom: var(--spacing-sm);
      font-weight: 500;
      color: var(--text-regular);
      font-size: var(--font-size-base);
    }

    /* 备注文本框样式 */
    .comment-textarea {
      width: 100%;
      padding: var(--spacing-md);
      border: 1px solid var(--border-base);
      border-radius: var(--border-radius-base);
      font-size: var(--font-size-base);
      font-family: inherit;
      transition: all 0.3s ease;
      background-color: var(--bg-white);
      color: var(--text-primary);
      resize: vertical;
      min-height: 100px;
      line-height: var(--line-height-lg);
    }

    .comment-textarea:focus {
      outline: none;
      border-color: var(--primary-color);
      box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.2);
    }

    .comment-textarea::placeholder {
      color: var(--text-placeholder);
      font-style: italic;
    }

    .comment-textarea:hover {
      border-color: var(--primary-color);
    }

    /* 错误消息样式 */
    .error-message {
      background-color: #fff2f0;
      color: var(--danger-color);
      padding: var(--spacing-md) var(--spacing-lg);
      border-radius: var(--border-radius-base);
      margin-bottom: var(--spacing-lg);
      border: 1px solid #ffccc7;
      font-size: var(--font-size-base);
    }

    /* 加载状态样式 */
    .loading-state {
      text-align: center;
      padding: 60px 20px;
      color: var(--text-secondary);
      min-height: 300px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: var(--spacing-md);
    }

@media (max-width: 768px) {
  .info-grid {
    grid-template-columns: 1fr;
  }
  
  .checkbox-group,
  .radio-group {
    flex-direction: column;
  }
  
  .extra-props-list {
    flex-direction: column;
  }
  
  .form-component-card {
    padding: 12px;
  }
  
  .header-actions {
    flex-direction: column;
    gap: 8px;
  }
  
  .modal-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }


    .modal-sm {
      max-width: 500px;
    }
    
    .form-group {
      margin-bottom: 20px;
    }
    
    .form-label {
      display: block;
      margin-bottom: 8px;
      font-weight: 500;
      color: #333;
    }
    
    .form-control {
      width: 100%;
      padding: 8px 12px;
      border: 1px solid #d9d9d9;
      border-radius: 4px;
      font-size: 14px;
      transition: all 0.3s;
    }
    
    .form-control:focus {
      outline: none;
      border-color: #40a9ff;
      box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
    }
    
    .error-message {
      background-color: #fff1f0;
      color: #ff4d4f;
      padding: 12px;
      border-radius: 4px;
      margin-bottom: 16px;
      font-size: 14px;
    }
  }
</style>